home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / scheme / pcscheme / ti / pcscm3_3 / pkxli.arc / SOUND.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-06-07  |  6.3 KB  |  250 lines

  1.       name      sound
  2.       title   PC Scheme XLI interface to sound
  3.       page      84,120
  4.  
  5.  
  6.       comment ~
  7.  
  8.    This program provides access to the PC's sound-generating devices.
  9.    It demonstrates an XLI interface written in assembly language.
  10.  
  11.    User documentation is available under XLI\SOUND.DOC.  SOUND.EXE is
  12.    already provided and can be used immediately by inserting its pathname
  13.    in your .XLI control file.
  14.  
  15.    To generate SOUND.EXE yourself, do the following (substituting
  16.    directory names and setting the path as needed; Microsoft's
  17.    Macro Assembler version 4.0 was used):
  18.  
  19.         masm sound;
  20.     link sound;
  21.  
  22.          ~
  23.  
  24.  
  25. DATA      segment byte public 'DATA'
  26.       assume  DS:DATA
  27. datastart =      $
  28.  
  29. ;-----------------------------------------------------------------------------
  30. ;    Equates
  31. ;-----------------------------------------------------------------------------
  32. ppi_port   equ    61h        ;Programmable Peripheral Interface port#
  33. timer_port equ  42h        ;timer chip port#
  34.                 ;reset timer is port# + 1
  35. timer_mask equ  00000001b    ;mask to extract timer bit    1=on
  36. spkr_mask  equ  00000010b    ;mask to extract speaker bit    1=on
  37.  
  38. ;-----------------------------------------------------------------------------
  39. ;    XLI
  40. ;-----------------------------------------------------------------------------
  41. ;;; ----- Equates -----
  42. ; offsets into the PSP
  43. term_addr equ    0Ah
  44. fb_addr      equ    5Ch
  45.  
  46. ;;; ----- Data structures -----
  47.  
  48. ; file block
  49. file_block label word
  50.     dw    4252h
  51.     dw    0011b        ;flags = 0,0,16-bit,near
  52.     dw    offset lookup_table, seg lookup_table
  53.     dw    offset parm_block, seg parm_block
  54.     dw    8 dup (0)    ;reserved
  55.  
  56. ; parameter block
  57. parm_block label word
  58.     dw    0        ;selector
  59.     dw    0        ;ssr
  60.     dw    8 dup (0)    ;ssr args
  61.     dw    8 dup (0)    ;reserved
  62.     dw    0        ;return value type
  63.     dw    4 dup (0)    ;return value
  64.     ; begin arguments
  65. over    dw    ?        ;overlay the 2 sound sources? (you and timer)
  66.                 ;  0 - enable/disable sound commands
  67.                 ;  1 - timer only 
  68.                 ;     (processor-speed independent)
  69.                 ;  2 - manual control only
  70.                 ;     (processor-speed dependent)
  71.                 ;  3 - overlay manual control with timer
  72.                 ;     (processor-speed dependent)
  73.                 ;  4 - speaker off
  74. freq    dw    ?        ;timer chip set to this frequency
  75. dura    dw    ?        ;duration
  76. pitch    dw    ?        ;pitch (silent section)
  77. pitch2  dw    ?        ;pitch (voiced section)
  78.  
  79. ; lookup table
  80. lookup_table label word
  81.     db    'sound//'
  82.  
  83. ; other needed values
  84. psp    dw    ?        ;PSP segment address
  85. psize   dw    ?        ;size of program in paragraphs
  86. xwait   dw    2 dup (?)    ;XLI wait address
  87. xbye    dw    2 dup (?)    ;XLI bye address
  88.  
  89. ;-----------------------------------------------------------------------------
  90. ;    Local data
  91. ;-----------------------------------------------------------------------------
  92. ;;; ----- Constants -----
  93. clock   dd    1193180        ;main clock frequency (Hz)
  94. ;;; ----- Variables -----
  95. tmask    db    ?        ;reflects state of timer mask
  96. enable  dw    1        ;enabled flag; 0=no, 1=yes
  97.  
  98. datasize =    $-datastart
  99. DATA    ends
  100.  
  101.  
  102. STACK   segment word stack 'STACK'
  103. stackstart =    $
  104.     dw    16 dup (?)
  105. stacksize  =    $ - stackstart
  106. STACK    ends
  107.  
  108.  
  109. PROG      segment byte public 'PROG'
  110.       assume  CS:PROG,DS:DATA
  111. progstart =      $
  112.  
  113. ;-----------------------------------------------------------------------------
  114. ;    The XLI interface.
  115. ;-----------------------------------------------------------------------------
  116.  
  117. main    proc    far            ;this file's initial entry point
  118.  
  119. ; Initialization
  120.  
  121.     mov    AX,data
  122.     mov    DS,AX
  123.     mov    psp,ES            ;save PSP@
  124.     mov    word ptr ES:fb_addr,offset file_block    ;poke file block@
  125.     mov    word ptr ES:fb_addr+2,seg file_block    ;into PSP
  126.     mov    AX,ES:term_addr        ;calc ptrs in PCS to jump to
  127.     add    AX,3
  128.     mov    xwait,AX
  129.     add    AX,3
  130.     mov    xbye,AX
  131.     mov    AX,ES:term_addr+2
  132.     mov    xwait+2,AX
  133.     mov    xbye+2,AX
  134.     mov    psize,plen        ;calc program size
  135.  
  136. ; Suspend this program until an XCALL comes in, or until PCS terminates.
  137.  
  138. hloop:    push    psp
  139.     push    psize
  140.     call    dword ptr [xwait]    ;connect to PCS
  141.     pop    ax
  142.     pop    ax
  143.     cmp    ax,0
  144.     jnz    case0
  145.     call    dword ptr [xbye]    ;disconnect from PCS
  146.  
  147. ;-----------------------------------------------------------------------------
  148. ;     The individual cases (just one, here).
  149. ;-----------------------------------------------------------------------------
  150.  
  151. case0:
  152.     cmp    over,0            ;enable/disable sound?
  153.     jnz    check            ;no, jump
  154.     mov    ax,freq            ;set flag appropriately
  155.     mov    enable,ax
  156.     mov    dx,0
  157.     jmp    short exit        ;turn off sound before exiting
  158.  
  159. check:  cmp    enable,0        ;is sound enabled?
  160.     jz    hloop            ;no, exit
  161. ;    
  162.     cmp    over,4            ;silence?
  163.     jnz    s1            ;no, jump
  164.     mov    dx,freq
  165. exit:    in    al,ppi_port        ;turn off speaker bit
  166.     and    al,not spkr_mask
  167.     out    ppi_port,al
  168.     cmp    dx,0            ;delay before returning?
  169.     jne    timed            ;yes, jump
  170.     jmp    hloop            ;no, return immediately to PC Scheme
  171.  
  172. s1:    cmp    over,1            ;timer only?
  173.     jnz    s2            ;no, jump
  174.     call    init_timer
  175.     in    al,ppi_port
  176.     or    al,spkr_mask OR timer_mask
  177.     out    ppi_port,al
  178.     cmp    dura,0            ;if duration=0,
  179.     jz    hloop            ;exit without turning sound off
  180. timed:    mov    tmask,0            ;x (time filler)
  181.     mov    bx,dura
  182. again1:    mov    cx,pitch
  183.     nop                ;x
  184.     nop                ;x
  185.     nop                ;x
  186. here1a:    loop    here1a
  187.     nop                ;x
  188.     nop                ;x
  189.     nop                ;x
  190.     or    al,tmask        ;x
  191.     mov    cx,pitch2
  192. here1b: loop    here1b
  193.     dec    bx
  194.     jnz    again1
  195.     xor    dx,dx            ;clear DX for exiting
  196.     jmp    exit
  197.  
  198. s2:    cmp    over,2            ;manual control only?
  199.     jnz    s3            ;no, jump
  200.     mov    tmask,0            ;reset timer-bit mask
  201. merge:    mov    bx,dura            ;BX is duration
  202.     in    al,ppi_port
  203. again2:    and    al,not (spkr_mask OR timer_mask)  ;turn off speaker
  204.     out    ppi_port,al
  205.     mov    cx,pitch        ;CX is first half of pitch half-cycle
  206. here2a:    loop    here2a
  207.     or    al,spkr_mask        ;turn on speaker
  208.     or    al,tmask        ;include timer bit state
  209.     out    ppi_port,al
  210.     mov    cx,pitch2        ;CX is second half of pitch half-cycle
  211. here2b: loop    here2b
  212.     dec    bx
  213.     jnz    again2
  214.     xor    dx,dx            ;clear DX for exiting
  215.     jmp    exit
  216.  
  217. s3:    cmp    over,3            ;both?
  218.     jnz    error            ;no, jump; error
  219.     call    init_timer
  220.     mov    tmask,timer_mask    ;set timer-bit mask
  221.     jmp    merge
  222.  
  223. error:    jmp    exit    
  224.  
  225. main    endp
  226.  
  227. init_timer proc
  228.     mov    al,182            ;reset timer chip
  229.     out    timer_port+1,al
  230.     mov    ax,word ptr clock    ;calc number to give to timer chip
  231.     mov    dx,word ptr clock+2    ;  = 1193180 / freq
  232.     mov    bx,freq
  233.     mov    cx,20            ;avoid underflow 
  234.     cmp    bx,cx            ;(occurs for divisors <= 18)
  235.     jge    it_10
  236.     mov    bx,cx
  237. it_10:    div    bx
  238.     out    timer_port,al        ;send number to timer chip
  239.     mov    al,ah
  240.     out    timer_port,al
  241.     ret
  242. init_timer endp
  243.  
  244. progsize =    $-progstart
  245. plen    equ    (progsize+datasize+stacksize+100h+20h)/16
  246.  
  247. PROG    ends
  248.     end    main
  249.  
  250.